package cn.mothin.frame.help;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.HashMap;
import java.util.Map;

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

public class JsHelper {
	private static JsHelper jsHelper=null;
	public static JsHelper getInstance(){
		if(jsHelper==null){
			jsHelper=new JsHelper();
			jsHelper.prepare();
		}
		return jsHelper;
	}
	
	private ScriptEngineManager mgr = new ScriptEngineManager();
	private ScriptEngine engine = mgr.getEngineByExtension("js");
	private String jsUtilContent;

	@SuppressWarnings("resource")
	public void prepare() {
		try {
			File jsUtilFile = new File(this.getClass().getClassLoader()
					.getResource("/js/js_util.packed.js").toURI());
			// File jsUtilFile = new File("d:/t/js_util.js");
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			FileInputStream in = new FileInputStream(jsUtilFile);
			int length = 0;
			byte[] bytes = new byte[1024];
			while ((length = in.read(bytes)) != -1) {
				out.write(bytes, 0, length);
			}
			jsUtilContent = out.toString();
			engine.eval(jsUtilContent);
		} catch (Exception e) {
			System.out.println(e);
		}
	}

	public String getFunctionName(String js) {
		int index = js.indexOf("function") + 8;
		int index2 = js.indexOf("(");
		StringBuilder sb = new StringBuilder();
		for (int i = index; i < index2; i++) {
			sb.append(js.charAt(i));
		}
		return sb.toString().replace(" ", "");
	}

	public String executeFunction(String fn, Object... params) {
		if (fn == null) {
			return null;
		}
		if (!jsUtilContent.contains(fn)) {
			return null;
		}

		Invocable invocable = (Invocable) engine;
		try {
			return invocable.invokeFunction(fn, params).toString();
		} catch (Exception e) {
			System.out.println(e);
		}
		return null;
	}

	public String execute(String js, Object... params) {
		if (js == null) {
			return null;
		}
		String fn = getFunctionName(js);
		if (!jsUtilContent.contains(fn)) {
			return null;
		}

		Invocable invocable = (Invocable) engine;
		try {
			return invocable.invokeFunction(fn, params).toString();
		} catch (Exception e) {
			System.out.println(e);
		}
		return null;
	}

	public static void main(String[] args) throws ClassNotFoundException {
		Map<String, Object> map = new HashMap<String, Object>();
		// map.put("a", 100);
		map.put("containNumber", 5);

		JsHelper js = new JsHelper();
		js.prepare();
		System.out
				.println(js.executeFunction("__proxyContainNumber", 500, map));
	}
}
